package com.yonyou.brigade.rtpnr.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.yonyou.brigade.basic_init.enums.ChannelEnum;
import com.yonyou.brigade.basic_init.model.BriChannel;
import com.yonyou.brigade.basic_init.props.PropUtil;
import com.yonyou.brigade.basic_init.service.IBriChannelService;
import com.yonyou.brigade.basic_init.service.IUserCenterService;
import com.yonyou.brigade.rtpnr.dao.RtpnrUserMapper;
import com.yonyou.brigade.rtpnr.model.JudgeAccountByLoginID;
import com.yonyou.brigade.rtpnr.model.RtpnrUser;
import com.yonyou.brigade.rtpnr.model.UpdateAccountInfo;
import com.yonyou.brigade.rtpnr.service.IRtpnrPublicService;
import com.yonyou.brigade.rtpnr.service.IRtpnrUserService;
import com.yonyou.ybzboot.starter.common.exception.BaseException;
import com.yonyou.ybzboot.starter.common.exception.CustomException;
import com.yonyou.ybzboot.uc.client.UcTenantServiceClient;
import com.yonyou.ybzboot.uc.dto.UcUserDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * Created by Administrator on 2018/6/12.
 */
@Service
public class RtpnrUserServiceImpl extends ServiceImpl<RtpnrUserMapper, RtpnrUser> implements IRtpnrUserService {

    @Autowired
    @Qualifier("rtpnrPublicServiceImpl")
    private IRtpnrPublicService rtpnrPublicService;

    @Autowired
    @Qualifier("briChannelServiceImpl")
    private IBriChannelService briChannelService;

    @Autowired
    private PropUtil propUtil;

    @Autowired
    @Qualifier("userCenterServiceImpl")
    private IUserCenterService iUserCenterService;

    @Value("${rtpnr.pub.tenant}")
    private String pubTenant;

    @Value("${rtpnr.pub.org}")
    private String pubOrg;

    @Autowired
    private UcTenantServiceClient ucTenantServiceClient;

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public synchronized Map syncRtpnrUsers(String tenant, String orgpk) {
        Map result = new HashMap();
        Map params = new HashMap();
        params.put("tenant", tenant);
        params.put("orgpk", orgpk);
        StringBuilder errorMsg = new StringBuilder();
        //获取所有用户
        List<UcUserDto> ucUserDtoByOrg = iUserCenterService.getUcUserDtoByOrg(tenant, orgpk);
        if (ucUserDtoByOrg == null || ucUserDtoByOrg.size() == 0) {
            result.put("code", "0");
            result.put("information", "没有待同步的用户");
            return result;
        }
        //已同步的用户
        Wrapper<RtpnrUser> wrapper = new EntityWrapper<>();
        wrapper.eq("tenant", tenant);
        wrapper.eq("org_pk", orgpk);
        List<RtpnrUser> rtpnrUsers1 = this.baseMapper.selectList(wrapper);
        Set<String> alreadyHasUserids = new HashSet<>();
        if (rtpnrUsers1 != null && rtpnrUsers1.size() > 0) {
            rtpnrUsers1.forEach(rtpnrUser -> {
                alreadyHasUserids.add(rtpnrUser.getUserId());
            });
        }
        //待同步的用户
        List<RtpnrUser> rtpnrUsers = new ArrayList<>();
        ucUserDtoByOrg.forEach(ucUserDto -> {
            //只处理未同步的用户
            if (!alreadyHasUserids.contains(ucUserDto.getUserId())) {
                RtpnrUser rtpnrUser = new RtpnrUser();
                rtpnrUser.setUserId(ucUserDto.getUserId());
                rtpnrUser.setTenant(tenant);
                rtpnrUser.setOrgpk(orgpk);
                rtpnrUser.setUserName(ucUserDto.getUserName());
                rtpnrUser.setMobile(ucUserDto.getPhone());
                rtpnrUser.setIsActivation("Y");
                rtpnrUser.setCardName(ucUserDto.getUserName());
                rtpnrUser.setEmail(ucUserDto.getEmail());
                rtpnrUser.setDepartment(ucUserDto.getDeptName());
                rtpnrUser.setStaffNum(ucUserDto.getUserCode());
                rtpnrUser.setAdmin(0);
                rtpnrUsers.add(rtpnrUser);
            }
        });
        if (rtpnrUsers != null && rtpnrUsers.size() > 0) {
            for (int i = 0; i < rtpnrUsers.size(); i++) {
                RtpnrUser rtpnrUser = rtpnrUsers.get(i);
                JSONObject resultTemp = rtpnrPublicService.createAccountInfo(tenant, orgpk, rtpnrUser);
                if (resultTemp != null && resultTemp.size() > 0) {
                    if (resultTemp.containsKey("ErrorCode") && resultTemp.getString("ErrorCode").equals("0")) {

                        String userKey = resultTemp.getString("UserKey");
                        String loginID = resultTemp.getString("LoginID");
                        rtpnrUser.setfUserKey(userKey);
                        rtpnrUser.setfLoginId(loginID);
                        this.baseMapper.insert(rtpnrUser);
                    } else if (resultTemp.containsKey("ErrorCode")) {
                        String errorInfo = rtpnrUser.getMobile() + resultTemp.getString("ErrorMsg");
                        logger.error(errorInfo);
                        errorMsg.append(errorInfo + "  ");
                    }
                } else {
                    throw new BaseException(-100, "同步用户返回为NULL");
                }

            }
        }
        String errorMsgStr = errorMsg.toString();
        if (errorMsgStr.length() == 0) {
            result.put("code", "0");
            result.put("information", "操作成功");
        } else {
            result.put("code", "-1");
            result.put("information", errorMsgStr);
        }
        return result;
    }

    /**
     * 更新用户信息
     *
     * @param tenant           租户ID
     * @param ucUserDtoByPhone 用户中心最新用户信息
     * @param oldRtpnrUser     商旅存储的友商旅用户信息
     * @param isPub            是否公户
     */
    public void updateRtpnrUserToRtpnr(String tenant, UcUserDto ucUserDtoByPhone, RtpnrUser oldRtpnrUser, boolean isPub) {
        if (!oldRtpnrUser.toCompareUcUserDto(ucUserDtoByPhone)) {
            //如果信息发生变化则进行更新
            RtpnrUser updateUser = new RtpnrUser();
            updateUser.setUserId(ucUserDtoByPhone.getUserId());
            updateUser.setTenant(tenant);
            updateUser.setOrgpk(ucUserDtoByPhone.getOrgPk());
            updateUser.setUserName(ucUserDtoByPhone.getUserName());
            updateUser.setMobile(ucUserDtoByPhone.getPhone());
            if (ucUserDtoByPhone.getDr().intValue() == 0) {
                updateUser.setIsActivation("Y");
            } else {
                updateUser.setIsActivation("N");
            }
            updateUser.setCardName(ucUserDtoByPhone.getUserName());
            updateUser.setEmail(ucUserDtoByPhone.getEmail());
            updateUser.setfLoginId(oldRtpnrUser.getfLoginId());
            if (isPub) {
                // 公户的部门由公司和部门名称组成
                updateUser.setDepartment(ucUserDtoByPhone.getOrgName() + "/" + ucUserDtoByPhone.getDeptName());
            } else {
                updateUser.setDepartment(ucUserDtoByPhone.getDeptName());
            }
            updateUser.setStaffNum(ucUserDtoByPhone.getPersonCode());
            updateUser.setAdmin(oldRtpnrUser.getAdmin());
            updateUser.setCategory(ucUserDtoByPhone.getRankName());

            UpdateAccountInfo updateAccountInfo = new UpdateAccountInfo();
            updateAccountInfo.setLoginId(updateUser.getfLoginId());
            updateAccountInfo.setCardName(updateUser.getUserName());
            updateAccountInfo.setMobile(updateUser.getMobile());
            updateAccountInfo.setUserName(updateUser.getUserName());
            updateAccountInfo.setEmail(updateUser.getEmail());
            updateAccountInfo.setDepartment(updateUser.getDepartment());
            updateAccountInfo.setCategory(updateUser.getCategory());
            updateAccountInfo.setStaffNum(updateUser.getStaffNum());
            // 判断是离职、启用还是更新
            if (updateUser.getIsActivation().equals("N")) {
                if (oldRtpnrUser.getIsActivation().equals("Y")) {
                    logger.info("开始调用离职接口：" + updateUser.getMobile());
                    //调用离职接口
                    updateAccountInfo.setUpdateType("3");
                }
            } else {
                if (updateUser.getIsActivation().equals("Y") && oldRtpnrUser.getIsActivation().equals("N")) {
                    logger.info("开始调用恢复接口：" + updateUser.getMobile());
                    updateAccountInfo.setUpdateType("4");
                    //调用注册接口  此处有个问题，如果一个租户内开了多组织，而且多组织在易购用的账号不一致，而用户又是修改了组织，此时会有问题
                } else {
                    //调用更新接口
                    logger.info("开始调用更新接口：" + updateUser.getMobile());
                    updateAccountInfo.setUpdateType("1");
                }
            }

            JSONObject resultTemp;
            if (isPub) {
                resultTemp = rtpnrPublicService.updateAccountInfo(pubTenant, pubOrg, updateAccountInfo);
            } else {
                resultTemp = rtpnrPublicService.updateAccountInfo(tenant, ucUserDtoByPhone.getOrgPk(), updateAccountInfo);
            }

            if (resultTemp != null && resultTemp.size() > 0) {
                if (resultTemp.containsKey("ErrorCode") && resultTemp.get("ErrorCode") != null && resultTemp.get("ErrorCode").toString().equals("0")) {
                    Wrapper<RtpnrUser> rtpnrUserWrapper = new EntityWrapper<>();
                    rtpnrUserWrapper.where("user_id={0}", updateUser.getUserId());
                    rtpnrUserWrapper.and("tenant={0}", updateUser.getTenant());
                    rtpnrUserWrapper.eq(RtpnrUser.PUB_ACCOUNT, isPub ? 1 : 0);
                    baseMapper.update(updateUser, rtpnrUserWrapper);
                    logger.info("更新完毕：" + updateUser.getMobile());
                } else {
                    logger.error("更新人员信息，中航易购返回错误：" + updateUser.getMobile());
                }
            }

        }
    }


    @Override
    public synchronized void syncRtpnrSingleUserByPhone(String tenant, String org, String phone, boolean isPub) {
        StringBuilder errorMsg = new StringBuilder();
        Map params = new HashMap();
        params.put("tenant", tenant);
        params.put("phone", phone);
        UcUserDto ucUserDtoByPhone = iUserCenterService.getCompleteUcUserDtoByPhone(phone, tenant);
        if (ucUserDtoByPhone == null) {
            logger.error("该用户在用户中心不存在" + phone);
            return;
        }
        Wrapper<RtpnrUser> wrapper = new EntityWrapper<>();
        wrapper.eq(RtpnrUser.USER_ID, ucUserDtoByPhone.getUserId());
        wrapper.eq("tenant", tenant);
        wrapper.eq("org_pk", org);
        if (isPub) {
            wrapper.eq("pub_account", 1);
        } else {
            wrapper.eq("pub_account", 0);
        }
        List<RtpnrUser> rtpnrUsers = this.baseMapper.selectList(wrapper);
        if (rtpnrUsers != null && rtpnrUsers.size() > 0) {
            //如果已经同步过，暂不处理
        } else {
            RtpnrUser rtpnrUser = new RtpnrUser();
            rtpnrUser.setUserId(ucUserDtoByPhone.getUserId());
            rtpnrUser.setTenant(tenant);
            rtpnrUser.setOrgpk(org);
            rtpnrUser.setUserName(ucUserDtoByPhone.getUserName());
            rtpnrUser.setMobile(ucUserDtoByPhone.getPhone());
            rtpnrUser.setIsActivation("Y");
            rtpnrUser.setCardName(ucUserDtoByPhone.getUserName());
            rtpnrUser.setEmail(ucUserDtoByPhone.getEmail());
            rtpnrUser.setDepartment(ucUserDtoByPhone.getDeptName());
            rtpnrUser.setStaffNum(ucUserDtoByPhone.getPersonCode());
            rtpnrUser.setAdmin(0);
            rtpnrUser.setCategory(ucUserDtoByPhone.getRankName());
            if (isPub) {
                rtpnrUser.setPubAccount("1");
                rtpnrUser.setDepartment(ucUserDtoByPhone.getOrgName() + "/" + ucUserDtoByPhone.getDeptName());
            } else {
                rtpnrUser.setPubAccount("0");
            }
            JSONObject resultTemp;
            if (isPub) {
                resultTemp = rtpnrPublicService.createAccountInfo(pubTenant, pubOrg, rtpnrUser);
            } else {
                resultTemp = rtpnrPublicService.createAccountInfo(tenant, org, rtpnrUser);
            }

            if (resultTemp != null && resultTemp.size() > 0) {
                if ((resultTemp.containsKey("ErrorCode") && resultTemp.getString("ErrorCode").equals("0")) || (resultTemp.getString("ErrorMsg").equals(""))) {
                    String loginID = resultTemp.getString("LoginID");
                    String userKey = resultTemp.getString("UserKey");
                    rtpnrUser.setfUserKey(userKey);
                    rtpnrUser.setfLoginId(loginID);
                    this.baseMapper.insert(rtpnrUser);
                } else if (resultTemp.containsKey("ErrorCode")) {
                    String errorInfo = rtpnrUser.getMobile() + resultTemp.getString("ErrorMsg");
                    logger.error(errorInfo);
                    errorMsg.append(errorInfo + "  ");
                    throw new BaseException(-100, errorInfo);
                }
            } else {
                throw new BaseException(-100, "同步用户返回为NULL");
            }
        }
    }

    /**
     * 用户中心添加用户触发的用户同步
     *
     * @param tenant
     * @param org
     * @param ucUserDtoList
     */
    @Override
    public void syncUsersByUserCenterListener(String tenant, String org, List<UcUserDto> ucUserDtoList) {
        if (!CollectionUtils.isEmpty(ucUserDtoList)) {
            BriChannel briChannel = briChannelService.getEnableInfoByTenantOrg(tenant, org, ChannelEnum.RTPNR.getName());
            for (UcUserDto ucUserDto : ucUserDtoList) {
                RtpnrUser rtpnrUser = new RtpnrUser();
                rtpnrUser.setUserId(ucUserDto.getUserId());
                rtpnrUser.setTenant(tenant);
                rtpnrUser.setOrgpk(org);
                rtpnrUser.setUserName(ucUserDto.getUserName());
                rtpnrUser.setMobile(ucUserDto.getPhone());
                rtpnrUser.setIsActivation("Y");
                rtpnrUser.setCardName(ucUserDto.getUserName());
                rtpnrUser.setEmail(ucUserDto.getEmail());
                rtpnrUser.setDepartment(ucUserDto.getDeptName());
                rtpnrUser.setStaffNum(ucUserDto.getPersonCode());
                if (!StringUtils.isEmpty(briChannel.getPhone()) && briChannel.getPhone().equals(ucUserDto.getPhone())
                        && !StringUtils.isEmpty(briChannel.getOrgpk()) && briChannel.getOrgpk().equals(ucUserDto.getOrgPk())) {
                    rtpnrUser.setAdmin(1);
                } else {
                    rtpnrUser.setAdmin(0);
                }
                rtpnrUser.setCategory(ucUserDto.getRankName());
                JSONObject resultTemp = rtpnrPublicService.createAccountInfo(tenant, org, rtpnrUser);
                if (resultTemp != null && resultTemp.size() > 0) {
                    if ((resultTemp.containsKey("ErrorCode")
                            && resultTemp.getString("ErrorCode").equals("0"))
                            || (resultTemp.getString("ErrorMsg").equals(""))) {

                        String userKey = resultTemp.getString("UserKey");
                        String loginID = resultTemp.getString("LoginID");
                        rtpnrUser.setfUserKey(userKey);
                        rtpnrUser.setfLoginId(loginID);
                        this.baseMapper.insert(rtpnrUser);
                    } else if (resultTemp.containsKey("ErrorCode")) {
                        String errorInfo = rtpnrUser.getMobile() + resultTemp.getString("ErrorMsg");
                        logger.error(errorInfo);
                    }
                } else {
                    logger.error("同步用户返回为NULL");
                }
            }
        }

    }

    /**
     * 用户中心修改用户触发的用户同步
     *
     * @param tenant
     * @param org
     * @param ucUserDtoList
     */
    @Override
    public void updateUserByUserCenterListener(String tenant, String org, List<UcUserDto> ucUserDtoList) {
        ucUserDtoList.forEach(ucUserDto -> {
            String userId = ucUserDto.getUserId();
            Wrapper<RtpnrUser> wrapper = new EntityWrapper<>();
            wrapper.eq(RtpnrUser.TENANT, tenant);
            wrapper.eq(RtpnrUser.ORGPK, org);
            wrapper.eq(RtpnrUser.USER_ID, userId);
            List<RtpnrUser> rtpnrUserList = this.baseMapper.selectList(wrapper);
            if (rtpnrUserList != null && rtpnrUserList.size() > 0) {
                RtpnrUser rtpnrUser = rtpnrUserList.get(0);
                String loginId = rtpnrUser.getfLoginId();
                UpdateAccountInfo updateAccountInfo = new UpdateAccountInfo();
                updateAccountInfo.setLoginId(loginId);
                updateAccountInfo.setUpdateType("1");

                updateAccountInfo.setMobile(ucUserDto.getPhone());
                updateAccountInfo.setUserName(ucUserDto.getUserName());
                updateAccountInfo.setStaffNum(ucUserDto.getPersonCode());
                updateAccountInfo.setDepartment(ucUserDto.getDeptName());

                JSONObject jsonObject = rtpnrPublicService.updateAccountInfo(tenant, org, updateAccountInfo);
                String errorCode = jsonObject.getString("ErrorCode");
                if ("0".equals(errorCode)) {
                    rtpnrUser.setMobile(ucUserDto.getPhone());
                    rtpnrUser.setUserName(ucUserDto.getUserName());
                    rtpnrUser.setStaffNum(ucUserDto.getPersonCode());
                    rtpnrUser.setDepartment(ucUserDto.getDeptName());

                    this.baseMapper.updateById(rtpnrUser);
                }
            }
        });
    }

    /**
     * 用户中心删除用户触发的用户同步
     *
     * @param tenant
     * @param org
     * @param userIdList
     */
    @Override
    public void deleteUserByUserCenterListener(String tenant, String org, List<String> userIdList) {
        userIdList.forEach(userId -> {
            Wrapper<RtpnrUser> wrapper = new EntityWrapper<>();
            wrapper.eq(RtpnrUser.TENANT, tenant);
            wrapper.eq(RtpnrUser.ORGPK, org);
            wrapper.eq(RtpnrUser.USER_ID, userId);
            List<RtpnrUser> rtpnrUserList = this.baseMapper.selectList(wrapper);
            if (rtpnrUserList != null && rtpnrUserList.size() > 0) {
                RtpnrUser rtpnrUser = rtpnrUserList.get(0);
                String loginId = rtpnrUser.getfLoginId();
                UpdateAccountInfo updateAccountInfo = new UpdateAccountInfo();
                updateAccountInfo.setLoginId(loginId);
                updateAccountInfo.setUpdateType("3");

                updateAccountInfo.setMobile(rtpnrUser.getMobile());
                updateAccountInfo.setUserName(rtpnrUser.getUserName());
                updateAccountInfo.setStaffNum(rtpnrUser.getStaffNum());
                updateAccountInfo.setDepartment(rtpnrUser.getDepartment());

                JSONObject jsonObject = rtpnrPublicService.updateAccountInfo(tenant, org, updateAccountInfo);
                String errorCode = jsonObject.getString("ErrorCode");
                if ("0".equals(errorCode)) {
                    this.baseMapper.deleteById(rtpnrUser);
                }

            }
        });
    }

    @Override
    public String loginUrl(String tenant, String org, String phone, String pageType, String pcOrH5, String jsonExt) {
        String resultUrl = "";
        BriChannel briChannel = briChannelService.getEnableInfoByTenantOrg(tenant, org, ChannelEnum.RTPNR.getName());
        // 是否走公户逻辑
        boolean isPub = false;
        if (briChannel == null) {
            // 根据租户和组织获取不到开通信息则进入公共租户
            briChannel = briChannelService.getEnableInfoByTenantOrg(pubTenant, pubOrg, ChannelEnum.RTPNR.getName());
            isPub = true;
            if (briChannel == null) {
                throw new CustomException("友商旅公共账户配置错误");
            }
        }

        UcUserDto ucUserDtoByPhoneTemp = iUserCenterService.listCompleteUcUserByUserMobiles4admin(phone, tenant);
        List<RtpnrUser> rtpnrUsers = new ArrayList<>();
        Wrapper<RtpnrUser> rtpnrUserWrapper = new EntityWrapper<>();
        rtpnrUserWrapper.eq(RtpnrUser.TENANT, tenant);
        if (ucUserDtoByPhoneTemp != null) {
            rtpnrUserWrapper.eq(RtpnrUser.USER_ID, ucUserDtoByPhoneTemp.getUserId());
            if (isPub) {
                rtpnrUserWrapper.eq("pub_account", "1");
            } else {
                rtpnrUserWrapper.eq("pub_account", "0");
            }
            rtpnrUsers = this.baseMapper.selectList(rtpnrUserWrapper);
        } else {
            logger.info("用户中心查无此人" + phone);
            return propUtil.getNO_ACCESS_URL();
        }
//        if (BriChannel.NEEDSYNCUSER == briChannel.getNeedSyncUser()) {
            if (CollectionUtils.isEmpty(rtpnrUsers)) {
                syncRtpnrSingleUserByPhone(tenant, org, phone, isPub);
                rtpnrUsers = this.baseMapper.selectList(rtpnrUserWrapper);
                if (rtpnrUsers == null || rtpnrUsers.size() == 0) {
                    resultUrl = propUtil.getNO_ACCESS_URL();
                    return resultUrl;
                }
            } else {
                updateRtpnrUserToRtpnr(tenant, ucUserDtoByPhoneTemp, rtpnrUsers.get(0), isPub);
                rtpnrUsers = this.baseMapper.selectList(rtpnrUserWrapper);
            }
//        }
        RtpnrUser user = rtpnrUsers.get(0);
        if (user.getCategory().equals("N")) {
            return propUtil.getNO_ACCESS_URL();
        }
        JudgeAccountByLoginID loginID = new JudgeAccountByLoginID();
        loginID.setLoginID(user.getfLoginId());
        loginID.setUserKey(user.getfUserKey());
        if (pcOrH5.toLowerCase().equals("pc")) {
            loginID.setLoginJump("PC");
        } else if (pcOrH5.toLowerCase().equals("h5")) {
            loginID.setLoginJump("H5");
        }

        if ("flight".equals(pageType)) {
            loginID.setFunCode("MenuFL02");
        } else if ("hotel".equals(pageType)) {
            loginID.setFunCode("MenuFL04");
        } else if ("train".equals(pageType)) {
            loginID.setFunCode("MenuFL05");
        } else {
            loginID.setFunCode("MenuFL01");
        }

        JSONObject resultResponse;
        if (isPub) {
            logger.info("tenant:" + tenant + ",org:" + org + ",loginID:" + loginID);
            resultResponse = rtpnrPublicService.ssoLogin(pubTenant, pubOrg, loginID);
        } else {
            logger.info("tenant:" + tenant + ",org:" + org + ",loginID:" + loginID);
            resultResponse = rtpnrPublicService.ssoLogin(tenant, org, loginID);
        }

        if (resultResponse != null && resultResponse.containsKey("jumpUrl")) {
            return (String) resultResponse.get("jumpUrl");
        }
        return propUtil.getNO_ACCESS_URL();
    }
}
